" .vimrc - Vim configuration file.
" LastChange: 2023-12-23

" COLORS SETTINGS: {{{1
" To use VIM settings, out of VI compatible mode.
set nocompatible
" Enable file type detection.
filetype plugin indent on
" Syntax highlighting.
syntax on
" Setting colorscheme
color mycolor
" 背景颜色设置（默认适应白色底色，深色底色需要打开，可提高文字对比度）
set background=dark

"去掉提示下划线，提示改为粗体，背景黑色高亮(深色主题先这个选项)
highlight CursorLine guifg=NONE gui=bold cterm=bold ctermbg=black
"去掉提示下划线，提示改为粗体
"highlight CursorLine gui=bold cterm=bold

" BASE SETTINGS: {{{1

" 自动缩进
set autoindent
" 自动读取文件变化
set autoread
" 自动写入文件
set autowrite
" 允许退格键删除任何字符
set backspace=indent,eol,start
" 使用 C 语言的缩进风格
set cindent

" 高亮当前行
set cursorline


" 文件编码设置
set fileencodings=utf-8,gb2312,gbk,gb18030
" 文件格式设置为 Unix 格式
set fileformat=unix

" 启用代码折叠
set foldenable
" 折叠方法使用标记,在代码中插入 // {{{ 表示折叠的开始，// }}} 表示折叠的结束
set foldmethod=marker

" 帮助窗口高度
set helpheight=10
" 设置帮助语言为中文
set helplang=cn
" 记录历史命令数
set history=100
" 高亮搜索结果
set hlsearch
" 忽略大小写进行搜索
set ignorecase
" 逐步搜索
set incsearch
" 显示状态行
set laststatus=2
" 弹出菜单高度
set pumheight=10
" 显示标尺
set ruler
" 光标距离窗口底部和顶部的行数
set scrolloff=5
" 显示命令
set showcmd
" 智能缩进
set smartindent
" 智能大小写搜索
set smartcase
" 设置终端编码为 UTF-8
set termencoding=utf-8
" 允许使用 h 和 l 键换行
set whichwrap=h,l
" 命令行文件补全忽略文件类型
set wildignore=*.bak,*.o,*.e,*~
" 启用命令行补全
set wildmenu
" 启用列表和完整模式的补全
set wildmode=list:longest,full
" 设置 C 语言的缩进选项 “:” 开始行不缩进
set cinoptions+=:
"}}}
" 设置 C 语言的缩进选项 “:,(” 开始行不缩进
"set cinoptions+=:,(0
" 缩进宽度
" set shiftwidth=8
" 隐藏不活动的缓冲区
" set hidden
" 按 Tab 键时使用空格代替制表符
" set noexpandtab
" 禁用备份文件
set nobackup

" 启用鼠标支持
set mouse=
" 显示行号
set number
" 禁用自动换行
set nowrap
" 制表符宽度
" set tabstop=8
" 文本宽度限制（注释掉表示不限制）
" set textwidth=80
" GUI模式隐藏菜单栏
" set guioptions-=T
" set guioptions-=m
" set guioptions-=r
" set guioptions-=l

" AUTO COMMANDS: {{{1
" auto expand tab to blanks
"autocmd FileType c,cpp set expandtab
" Restore the last quit position when open file.
autocmd BufReadPost *
    \ if line("'\"") > 0 && line("'\"") <= line("$") |
    \     exe "normal g'\"" |
    \ endif
" 在 .postrc 文件中自动启用 Bash 脚本语法高亮
autocmd BufRead,BufNewFile .postrc set filetype=sh

" SHORTCUT SETTINGS: {{{1
" Set mapleader
" let mapleader=","
" Space to command mode.
nnoremap <space> :
vnoremap <space> :
" Switching between buffers.
nnoremap <C-h> <C-W>h
nnoremap <C-j> <C-W>j
nnoremap <C-k> <C-W>k
nnoremap <C-l> <C-W>l
inoremap <C-h> <Esc><C-W>h
inoremap <C-j> <Esc><C-W>j
inoremap <C-k> <Esc><C-W>k
inoremap <C-l> <Esc><C-W>l
" "cd" to change to open directory.
let OpenDir=system("pwd")
nmap <silent> <leader>cd :exe 'cd ' . OpenDir<cr>:pwd<cr>

" PLUGIN SETTINGS: {{{1
" taglist.vim
let g:Tlist_Auto_Update=1
let g:Tlist_Process_File_Always=1
let g:Tlist_Exit_OnlyWindow=1
let g:Tlist_Show_One_File=1
let g:Tlist_WinWidth=25
let g:Tlist_Enable_Fold_Column=0
let g:Tlist_Auto_Highlight_Tag=1
" NERDTree.vim
let g:NERDTreeWinPos="right"
let g:NERDTreeWinSize=25
let g:NERDTreeShowLineNumbers=1
let g:NERDTreeQuitOnOpen=1
" cscope.vim
if has("cscope")
    set csto=1
    set cst
    set nocsverb
    if filereadable("cscope.out")
        cs add cscope.out
    endif
    set csverb
endif
" OmniCppComplete.vim
"set nocp 
"filetype plugin on 
let g:OmniCpp_DefaultNamespaces=["std"]
let g:OmniCpp_MayCompleteScope=1
let g:OmniCpp_SelectFirstItem=2

" VimGDB.vim
if has("gdb")
	set asm=0
	let g:vimgdb_debug_file=""
	run macros/gdb_mappings.vim
endif
" LookupFile setting
let g:LookupFile_TagExpr='"./tags.filename"'
let g:LookupFile_MinPatLength=2
let g:LookupFile_PreserveLastPattern=0
let g:LookupFile_PreservePatternHistory=1
let g:LookupFile_AlwaysAcceptFirst=1
let g:LookupFile_AllowNewFiles=0
" Man.vim
source $VIMRUNTIME/ftplugin/man.vim
" snipMate
"let g:snips_author="Du Jianfeng"
"let g:snips_email="cmdxiaoha@163.com"
"let g:snips_copyright="SicMicro, Inc"
" plugin shortcuts
function! RunShell(Msg, Shell)
	echo a:Msg . '...'
	call system(a:Shell)
	echon 'done'
endfunction


" 定义函数切换行号显示
function! ToggleLineNumbers()
  if &number
"    set norelativenumber
    set nonumber
    set mouse=
    set wrap
  else
    set number
    set mouse=a
    set nowrap
  endif
endfunction

" 按下F7键时切换行号显示及鼠标使能,当启用鼠标后，终端鼠标选中功能需要按下shift，否则默认为vim内部光标选项
nnoremap <F7> :call ToggleLineNumbers()<CR>

function! AutocompleteSwitch()
	if g:acpstat == 1
		AcpDisable
		let g:AcpSTATUS = "[补全关闭]"
		"    let b:SuperTabDisabled = 1
		let g:acpstat = 0
	else
		AcpEnable
		let g:AcpSTATUS = ""
		"    let b:SuperTabDisabled = 0
		let g:acpstat = 1
	endif
endfunction
"F8 打开关闭ACP自动补齐
nnoremap <F8> :call AutocompleteSwitch()<CR>

function! RunScriptx()
  " 获取当前选中的函数名
  let selected_text = expand("<cword>")
  let buffer_name = selected_text . "\\ [Call\\ By]"
  " 清除之前可能存在的结果
  silent! bdelete! RunScriptOutput
  " 执行脚本并将结果保存到新建缓冲区
  let output = system("~/.vim/shell/cscopegetcallbytree.sh " . selected_text)
  " 创建一个新的竖向分屏
  vsplit
  " 切换到新分屏中的缓冲区
  wincmd l
  " 创建一个新的缓冲区
  enew
  setlocal buftype=nofile bufhidden=hide nobuflisted noswapfile
  put=output

  " 设置只读，禁止保存
  setlocal readonly
  setlocal nomodifiable

  " 将新建缓冲区命名为 buffer_name
  execute "file " . buffer_name
endfunction

" 将F8键映射到刚刚定义的函数
map <F9> :call RunScriptx()<CR><CR>

nmap  <F2> :TlistToggle<cr>
nmap  <F3> :NERDTreeToggle<cr>
nmap  <F4> :MRU<cr>
nmap  <F5> <Plug>LookupFile<cr>
nmap  <F6> :vimgrep /<C-R>=expand("<cword>")<cr>/ **/*.c **/*.h<cr><C-o>:cw<cr>
"nmap  <F9> :call RunShell("Generate tags", "ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .")<cr>
"nmap <F10> :call HLUDSync()<cr>
"nmap <F11> :call RunShell("Generate filename tags", "~/.vim/shell/genfiletags.sh")<cr>
"nmap <F12> :call RunShell("Generate cscope", "cscope -Rb")<cr>:cs add cscope.out<cr>
nmap <leader>sa :cs add cscope.out<cr>
nmap <leader>ss :cs find s <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sg :cs find g <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sc :cs find c <C-R>=expand("<cword>")<cr><cr>
nmap <leader>st :cs find t <C-R>=expand("<cword>")<cr><cr>
nmap <leader>se :cs find e <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sf :cs find f <C-R>=expand("<cfile>")<cr><cr>
nmap <leader>si :cs find i <C-R>=expand("<cfile>")<cr><cr>
nmap <leader>sd :cs find d <C-R>=expand("<cword>")<cr><cr>
nmap <leader>zz <C-w>o
nmap <leader>gs :GetScripts<cr>

nnoremap <C-ScrollWheelClick> :cs find s <C-R>=expand("<cword>")<CR><CR>
" }}}

nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-\>i :cs find i <C-R>=expand("<cfile>")<CR><CR>
nmap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap m <C-\>
nmap , \

let Tlist_Show_One_File=0
" set noswapfile
" set tags+=/usr/include/tags
set tags+=./tags
map ta :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
cmap man Man

set listchars=tab:>-,trail:-

autocmd FileType * setlocal complete-=] complete-=}
let g:syntastic_mode_map = { 'mode': 'passive' }

" 去掉大小写转换快捷键避免66布局键盘误触
noremap ~ <Nop>

" 自动去除行尾空格
" autocmd BufWritePre *.c,*.h,*.cpp,*.hpp,*.cxx,*.hxx,*.cc,*.hh,*.c++,*.h++,*.sh,[mM]akefile :%s/\s\+$//e

" 将 Supertab 的补全触发键改为 SHIFT+Tab 和 SHIFT+p
let g:SuperTabMappingForward = '<S-tab>'
"let g:SuperTabMappingBackward = '<S-Tab>'

"默认开启自动补齐，并添加补齐状态提醒
let g:acp_enableAtStartup = 1
let g:acpstat = g:acp_enableAtStartup

if g:acpstat == 0
"	let g:AcpSTATUS = "[补全关闭 F8开启]"
	let g:AcpSTATUS = "[F7鼠标模式 F8开启补全]"
else
	let g:AcpSTATUS = ""
endif

"在状态栏追加 acp状态
set statusline=%f%m%r%h\ %=%l,%c%V\ %P\ %{g:AcpSTATUS}

"设置老板键延迟sm数
set timeoutlen=2000

" Echo translation in the cmdline
nmap <silent> <Leader>t <Plug>Translate
vmap <silent> <Leader>t <Plug>TranslateV
" Display translation in a window
nmap <silent> <Leader>w <Plug>TranslateW
vmap <silent> <Leader>w <Plug>TranslateWV
" Translate the text in clipboard
" nmap <silent> <Leader>x <Plug>TranslateX
"let g:translator_default_engines = ['youdao']
